#include "Simulacion.h"

Simulacion::Simulacion(int cantidadEstacionamientos) {
	//cout << "Simulador con pid : " << getpid() << endl;
	sim = new SimulacionHandler();
	this->cantidadEstacionamientos = cantidadEstacionamientos;
	this->entradaDeAutos = new Cola<autoSerializable>(
			Utils::NOMBRE_ARCHIVO_ENTRADA, 'A');
	lock = new LockFile((char *) Utils::NOMBRE_ARCHIVO_PARA_LOG);
	string mensaje = "Se crea simulacion con  "
			+ to_string(cantidadEstacionamientos) + " estacionamientos\n";
	char* log = (char*) mensaje.c_str();
	lock->escribirConLock(log, strlen(log));
}

void Simulacion::empezar() {
	string mensaje = "Inicia Simulacion";
	char* log = (char*) mensaje.c_str();
	lock->escribirConLock(log, strlen(log));
	int i = 0;
	SignalHandler::getInstance()->registrarHandler(SIGINT, sim);
	while (sim->getGracefulQuit() == 0) {
		sleep(2);
		int nroEst = (rand() % cantidadEstacionamientos) + 1;
		if (sim->getGracefulQuit() == 0) {
			Auto autoEntrando(i, nroEst);
			this->ingresarAuto(&autoEntrando);
			string mensaje = "Vino el Auto : " + to_string(i)
					+ " al estacionamiento : " + to_string(nroEst) + "\n";
			char* log = (char*) mensaje.c_str();
			lock->escribirConLock(log, strlen(log));
			i++;
		}
	}
	this->terminar();
}

void Simulacion::ingresarAuto(Auto* autoAEntrar) {
	autoSerializable autoSerializable;
	autoSerializable.mtype = autoAEntrar->getNumeroEstacionamiento();
	autoSerializable.idAuto = autoAEntrar->getId();
	int resultado = entradaDeAutos->escribir(autoSerializable);
	if (resultado == -1) {
		cout << "Error al escribir auto : " << autoAEntrar->getId() << endl;
	}
}

void Simulacion::terminar() {
	for (int i = 1; i <= cantidadEstacionamientos; i++) {
		for (int j = 0; j < 3; j++) {
			autoSerializable autoSerializable;
			autoSerializable.mtype = i;
			autoSerializable.tipoMensaje = TIPO_MENSAJE_FIN;
			int resultado = entradaDeAutos->escribir(autoSerializable);
			if (resultado == -1) {
				cout
						<< "Error al escribir mensaje de fin a entrada de estacionamiento: "
						<< i << endl;
			}
		}
	}
	this->entradaDeAutos->destruir();
	string mensaje = "Termina simulacion con  "
			+ to_string(cantidadEstacionamientos) + " estacionamientos\n";
	char* log = (char*) mensaje.c_str();
	lock->escribirConLock(log, strlen(log));
}

Simulacion::~Simulacion() {
	delete this->entradaDeAutos;
}
